home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright (c) 1990-1992 Eugene Nelson
-
- This program demonstrates the suggested usage of the Cx Data Compression
- Library. It will compress and decompress a file of any size, containing
- any type of data. The compressed data is stored with 16 bit CRC's to
- help in detecting errors. It stores the file as blocks of data which
- have the following form:
-
- BLOCK
- ----------------------------------------------------
- 2 bytes - size of uncompressed block (USIZE)
- 2 bytes - size of compressed block (CSIZE)
- 2 bytes - 16 bit CRC (CRC)
- CSIZE - data (DATA)
- ----------------------------------------------------
-
- If a block cannot be compressed, the original data is stored, and
- USIZE and CSIZE will be the same. The CRC is computed on the
- compressed data.
-
- 2 bytes of 0 are stored at the end of the compressed file to indicate
- the end of file.
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <io.h>
- #include <fcntl.h>
- #include <sys\types.h>
- #include <sys\stat.h>
-
- #include "cx.h"
-
- /*-------------------------------------------------------------------------*/
- void USAGE(void)
- {
- printf("usage: cxf 1|2|3|t|d infile outfile\n");
- printf(" 1|2|3 - compress infile to outfile using method 1,2 or 3\n");
- printf(" d - decompress infile to outfile\n");
- printf(" t - test integrity of infile\n\n");
- printf(" Examples:\n");
- printf(" cxf 1 cxf.exe x.x\n");
- printf(" cxf t x.x\n");
- printf(" cxf d x.x y.y\n");
- exit (0);
- }
-
- /*-------------------------------------------------------------------------*/
- void QUIT(char *s)
- {
- printf("\n%s\n", s);
- exit (0);
- }
-
- /*-------------------------------------------------------------------------*/
- #define MALLOC(p,n) {if ((p = malloc(n)) == NULL) QUIT ("insufficient memory");}
- #define FREE(p) free(p)
- #define CREATE(s) open(s, O_WRONLY|O_CREAT|O_BINARY, S_IREAD|S_IWRITE)
- #define OPEN(s) open(s, O_RDWR|O_BINARY, 0)
- #define WRITE(f,b,n) {if (write(f, b, n) != n) QUIT ("could not write");}
- #define READ(f,b,n) {if (read(f, b, n) != n) QUIT ("could not read");}
- #define CLOSE(f) {if (close(f) != 0) QUIT ("could not close");}
-
- /*-------------------------------------------------------------------------*/
- void file_compress(char *dst, char *src, CXINT method, CXINT size)
- {
- int ifile, ofile;
- long ifilesize, ofilesize;
- CXINT j, k, crc;
- CXBUFF ibuff, obuff, tbuff;
-
- if ((ifile = OPEN(src)) == -1)
- QUIT ("could not open ifile");
-
- unlink(dst);
- if ((ofile = CREATE(dst)) == -1)
- QUIT ("could not open ofile");
-
- MALLOC(ibuff, size);
- MALLOC(obuff, size+CX_SLOP);
- MALLOC(tbuff, CX_C_MAXTEMP);
-
- ifilesize = ofilesize = 0;
- while (1)
- {
- printf(".");
-
- j = read(ifile, ibuff, size);
- WRITE(ofile, &j, CXINTSIZE);
- ifilesize += j;
- ofilesize += CXINTSIZE;
- if (j == 0)
- break;
-
- k = CX_COMPRESS(method, obuff, size, ibuff, j, tbuff, CX_C_MAXTEMP);
- switch (k)
- {
- case CX_ERR_METHOD:
- QUIT("unknown or unsupported method, evaluation version only allows CX_MEHTOD1");
-
- case CX_ERR_BUFFSIZE:
- QUIT("invallid input or output buffer size");
-
- case CX_ERR_TEMPSIZE:
- QUIT("invalid temporary buffer size");
- }
-
- WRITE(ofile, &k, CXINTSIZE);
-
- if (k == j) /* if block could not be compressed */
- {
- crc = CX_CRC(ibuff, k);
- WRITE(ofile, &crc, sizeof(crc));
- WRITE(ofile, ibuff, k)
- }
- else
- {
- crc = CX_CRC(obuff, k);
- WRITE(ofile, &crc, sizeof(crc));
- WRITE(ofile, obuff, k)
- }
-
- ofilesize += CXINTSIZE+sizeof(crc)+k;
- }
-
- FREE(ibuff);
- FREE(obuff);
- FREE(tbuff);
-
- CLOSE(ifile);
- CLOSE(ofile);
-
- printf("\n");
- printf("Insize: %10ld\n", ifilesize);
- printf("Outsize: %10ld\n", ofilesize);
- if (ifilesize != 0)
- printf("Percent: %10d", (ofilesize*100)/ifilesize);
- }
-
- /*-------------------------------------------------------------------------*/
- void file_decompress(char *dst, char *src)
- {
- int ifile, ofile;
- CXINT j, k, crc;
- CXBUFF ibuff, obuff, tbuff;
-
- if ((ifile = OPEN(src)) == -1)
- QUIT ("could not open ifile");
-
- if (dst != NULL)
- {
- unlink(dst);
- if ((ofile = CREATE(dst)) == -1)
- QUIT ("could not open ofile");
- }
-
- MALLOC(ibuff, CX_MAX_BUFFER+CX_SLOP);
- MALLOC(obuff, CX_MAX_BUFFER);
- MALLOC(tbuff, CX_D_MINTEMP);
-
- while (1)
- {
- printf(".");
-
- READ(ifile, &j, CXINTSIZE);
- if (j == 0)
- break;
-
- READ(ifile, &k, CXINTSIZE);
- READ(ifile, &crc, sizeof(crc));
- READ(ifile, ibuff, k);
-
- if (CX_CRC(ibuff, k) != crc)
- QUIT ("CRC error");
-
- if (j == k) /* if block is not compressed */
- {
- if (dst != NULL)
- WRITE(ofile, ibuff, j);
- }
- else
- {
- k = CX_DECOMPRESS(obuff, CX_MAX_BUFFER, ibuff, k, tbuff, CX_D_MINTEMP);
- switch (k)
- {
- case CX_ERR_INVALID:
- QUIT("data being compressed is corrupt, or was not compressed with Cx.");
-
- case CX_ERR_METHOD:
- QUIT("unknown or unsupported method, evaluation version only allows CX_MEHTOD1");
-
- case CX_ERR_BUFFSIZE:
- QUIT("End of Data symbol not found");
-
- case CX_ERR_TEMPSIZE:
- QUIT("invalid temporary buffer size");
- }
-
- if (k != j)
- QUIT("data being compressed is corrupt, or was not compressed with Cx.");
-
- if (dst != NULL)
- WRITE(ofile, obuff, j);
- }
- }
-
- FREE(ibuff);
- FREE(obuff);
- FREE(tbuff);
-
- CLOSE(ifile);
- if (dst != NULL)
- CLOSE(ofile);
- }
-
- /*-------------------------------------------------------------------------*/
- void main(int argc, char *argv[])
- {
- int ch;
-
- if (argc < 4)
- {
- if (argc < 3)
- USAGE();
-
- ch = toupper(argv[1][0]);
-
- if (ch == 'T')
- file_decompress(NULL, argv[2]);
- else if (ch == 'R')
- file_decompress(NULL, argv[2]);
- else
- USAGE();
- }
- else
- {
- ch = toupper(argv[1][0]);
-
- if (ch == '1')
- file_compress(argv[3], argv[2], CX_METHOD1, CX_MAX_BUFFER);
- else if (ch == '2')
- file_compress(argv[3], argv[2], CX_METHOD2, CX_MAX_BUFFER);
- else if (ch == '3')
- file_compress(argv[3], argv[2], CX_METHOD2, CX_MAX_BUFFER);
- else if (ch == 'D')
- file_decompress(argv[3], argv[2]);
- else
- USAGE();
- }
-
- QUIT ("Ok");
- }
-